home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Icon 8.1 / msm-1 / common.sit / literals.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-19  |  8.2 KB  |  261 lines  |  [TEXT/MPS ]

  1. #include "::h:gsupport.h"
  2. #include <ctype.h>
  3.  
  4. /*
  5.  * Prototype.
  6.  */
  7. unsigned short    *bitvect    Params((char *image,int len));
  8.  
  9. /*
  10.  * Within translators, csets are internally implemented as a bit vector made
  11.  *  from an array of unsigned shorts. For portability, only the lower 16
  12.  *  bits of these shorts are used.
  13.  */
  14. #define BVectIndx(c) (((unsigned char)c >> 4) & 0xf)
  15. #define BitInShrt(c) (1 << ((unsigned char)c & 0xf))
  16.  
  17. /*
  18.  * Macros used by escape() to advance to the next character and to
  19.  *  test the kind of character.
  20.  */
  21. #define NextChar(c) {c = *(*str_ptr)++; (*nchars_ptr)--;}
  22. #define isoctal(c) ((c)>='0'&&(c)<='7')    /* macro to test for octal digit */
  23.  
  24. #if !EBCDIC
  25. /*
  26.  * esctab - translates single-character escapes in string literals.
  27.  */
  28.  
  29. static unsigned char esctab[] = {
  30.    000,   001,     002,    003,   004,   005,   006,   007,   /* NUL-BEL */
  31.    010,   011,     012,    013,   014,   015,   016,   017,   /* BS -SI */
  32.    020,   021,     022,    023,   024,   025,   026,   027,   /* DLE-ETB */
  33.    030,   031,     032,    033,   034,   035,   036,   037,   /* CAN-US */
  34.    ' ',   '!',   '"',   '#',   '$',   '%',   '&',   '\'',  /* !"#$%&' */
  35.    '(',   ')',   '*',   '+',   ',',   '-',   '.',   '/',   /* ()*+,-./ */
  36.    000,   001,     002,    003,   004,   005,   006,   007,   /* 01234567 */
  37.    010,   011,     ':',   ';',   '<',   '=',   '>',   '?',   /* 89:;<=>? */
  38.    '@',   'A',   '\b',  'C',   0177,  033,   014,   'G',   /* @ABCDEFG */
  39.    'H',   'I',   'J',   'K',   '\n',  'M',  '\n',   'O',   /* HIJKLMNO */
  40.    'P',   'Q',   '\r',  'S',   '\t',  'U',   013,   'W',   /* PQRSTUVW */
  41.    'X',   'Y',   'Z',   '[',   '\\',  ']',   '^',   '_',   /* XYZ[\]^_ */
  42.    '`',   'a',   '\b',  'c',   0177,  033,   014,   'g',   /* `abcdefg */
  43.    'h',   'i',   'j',   'k',   '\n',  'm',   '\n',  'o',   /* hijklmno */
  44.    'p',   'q',   '\r',  's',   '\t',  'u',   013,   'w',   /* pqrstuvw */
  45.    'x',   'y',   'z',   '{',   '|',   '}',   '~',   0177,  /* xyz{|}~ */
  46.    0200,  0201,  0202,    0203,  0204,  0205,  0206,  0207,
  47.    0210,  0211,  0212,    0213,  0214,  0215,  0216,  0217,
  48.    0220,  0221,  0222,    0223,  0224,  0225,  0226,  0227,
  49.    0230,  0231,  0232,    0233,  0234,  0235,  0236,  0237,
  50.    0240,  0241,  0242,    0243,  0244,  0245,  0246,  0247,
  51.    0250,  0251,  0252,    0253,  0254,  0255,  0256,  0257,
  52.    0260,  0261,  0262,    0263,  0264,  0265,  0266,  0267,
  53.    0270,  0271,  0272,    0273,  0274,  0275,  0276,  0277,
  54.    0300,  0301,  0302,    0303,  0304,  0305,  0306,  0307,
  55.    0310,  0311,  0312,    0313,  0314,  0315,  0316,  0317,
  56.    0320,  0321,  0322,    0323,  0324,  0325,  0326,  0327,
  57.    0330,  0331,  0332,    0333,  0334,  0335,  0336,  0337,
  58.    0340,  0341,  0342,    0343,  0344,  0345,  0346,  0347,
  59.    0350,  0351,  0352,    0353,  0354,  0355,  0356,  0357,
  60.    0360,  0361,  0362,    0363,  0364,  0365,  0366,  0367,
  61.    0370,  0371,  0372,    0373,  0374,  0375,  0376,  0377,
  62.   };
  63. #else                    /* EBCDIC */
  64. /*
  65.  *  This is the EBCDIC table for handling escapes.
  66.  */
  67. static char esctab[] = {
  68.    0x00,  0x01,  0x02,  0x03,  0x04,  0x05,  0x06,  0x07,
  69.    0x08,  0x09,  0x0a,  0x0b,  0x0c,  0x0d,  0x0e,  0x0f,
  70.    0x10,  0x11,  0x12,  0x13,  0x14,  0x15,  0x16,  0x17,
  71.    0x18,  0x19,  0x1a,  0x1b,  0x1c,  0x1d,  0x1e,  0x1f,
  72.    0x20,  0x21,  0x22,  0x23,  0x24,  0x25,  0x26,  0x27,
  73.    0x28,  0x29,  0x2a,  0x2b,  0x2c,  0x2d,  0x2e,  0x2f,
  74.    0x30,  0x31,  0x32,  0x33,  0x34,  0x35,  0x36,  0x37,
  75.    0x38,  0x39,  0x3a,  0x3b,  0x3c,  0x3d,  0x3e,  0x3f,
  76.    ' ',   0x41,  0x42,  0x43,  0x44,  0x45,  0x46,  0x47,
  77.    0x48,  0x49,  0x4a,  0x4b,  0x4c,  0x4d,  0x4e,  0x4f,
  78.    0x50,  0x51,  0x52,  0x53,  0x54,  0x55,  0x56,  0x57,
  79.    0x58,  0x59,  0x5a,  0x5b,  0x5c,  0x5d,  0x5e,  0x5f,
  80.    0x60,  0x61,  0x62,  0x63,  0x64,  0x65,  0x66,  0x67,
  81.    0x68,  0x69,  0x6a,  0x6b,  0x6c,  0x6d,  0x6e,  0x6f,
  82.    0x70,  0x71,  0x72,  0x73,  0x74,  0x75,  0x76,  0x77,
  83.    0x78,  0x79,  0x7a,  0x7b,  0x7c,  0x7d,  0x7e,  0x7f,
  84.    0x80,  'a',   0x16,  'c',   0x07,  0x27,  0x0c,  'g',
  85.    'h',   'i',   0x8a,  0x8b,  0x8c,  0x8d,  0x8e,  0x8f,
  86.    0x90,  'j',   'k',   0x25,  'm',   0x15,  'o',   'p',
  87.    'q',   0x0d,  0x9a,  0x9b,  0x9c,  0x9d,  0x9e,  0x9f,
  88.    0xa0,  0xa1,  's',   0x05,  'u',   0x0b,  'w',   'x',
  89.    'y',   'z',   0xaa,  0xab,  0xac,  0xad,  0xae,  0xaf,
  90.    0xb0,  0xb1,  0xb2,  0xb3,  0xb4,  0xb5,  0xb6,  0xb7,
  91.    0xb8,  0xb9,  0xba,  0xbb,  0xbc,  0xbd,  0xbe,  0xbf,
  92.    0xc0,  'A',   0x16,  'C',   0x07,  0x27,  0x0c,  'G',
  93.    'H',   'I',   0xca,  0xcb,  0xcc,  0xcd,  0xce,  0xcf,
  94.    0xd0,  'J',   'K',   0x25,  'M',   0x15,  'O',   'P',
  95.    'Q',   0x0d,  0xda,  0xdb,  0xdc,  0xdd,  0xde,  0xdf,
  96.    0xe0,  0xe1,  'S',   0x05,  'U',   0x0b,  'W',   'X',
  97.    'Y',   'Z',   0xea,  0xeb,  0xec,  0xed,  0xee,  0xef,
  98.    0,   1,   2,   3,     4,     5,     6,     7,
  99.    8,   9,   0xfa,   0xfb,  0xfc,  0xfd,  0xfe,  0xff,
  100.    };
  101. #endif               /* EBCDIC */
  102.  
  103. /*
  104.  * escape - translate the character sequence following a '\' into the
  105.  *   single character it represents.
  106.  */
  107. static int escape(str_ptr, nchars_ptr)
  108. char **str_ptr;
  109. int *nchars_ptr;
  110.    {
  111.    register int c, nc, i;
  112.  
  113.    /*
  114.     * Note, it is impossible to have a character string ending with a '\',
  115.     *  something must be here.
  116.     */
  117.    NextChar(c)
  118.    if (isoctal(c)) {
  119.       /*
  120.        * translate an octal escape -- backslash followed by one, two, or three
  121.        *  octal digits.
  122.        */
  123.       c -= '0';
  124.       for (i = 2; *nchars_ptr > 0 && isoctal(**str_ptr) && i <= 3; ++i) {
  125.          NextChar(nc)
  126.          c = (c << 3) | (nc - '0');
  127.          }
  128.       return (c & 0377);
  129.       }
  130.    else if (c == 'x') {
  131.       /*
  132.        * translate a hexadecimal escape -- backslash-x followed by one or
  133.        *  two hexadecimal digits.
  134.        */
  135.       c = 0;
  136.       for (i = 1; *nchars_ptr > 0 && isxdigit(**str_ptr) && i <= 2; ++i) {
  137.          NextChar(nc)
  138.          if (nc >= 'a' && nc <= 'f')
  139.              nc -= 'a' - 10;
  140.          else if (nc >= 'A' && nc <= 'F')
  141.             nc -= 'A' - 10;
  142.          else if (isdigit(nc))
  143.              nc -= '0';
  144.          c = (c << 4) | nc;
  145.          }
  146.       return c;
  147.       }
  148.    else if (c == '^') {
  149.       /*
  150.        * translate a control escape -- backslash followed by caret and one
  151.        *  character.
  152.        */
  153.       if (*nchars_ptr <= 0)
  154.          return 0;           /* could only happen in a keyword */
  155.       NextChar(c)
  156.       return (c & 037);
  157.       }
  158.    else
  159.       return esctab[c];
  160.    }
  161.  
  162.  
  163. /*
  164.  * bitvect - convert cset literal into a bitvector
  165.  */
  166. unsigned short *bitvect(image, len)
  167. char *image;
  168. int len;
  169.    {
  170.    register int c;
  171.    register unsigned short *bv;
  172.    register int i;
  173.  
  174.    bv = 
  175.     (unsigned short *)alloc((unsigned int)((BVectSize)*sizeof(unsigned short)));
  176.    for (i = 0; i < BVectSize; ++i)
  177.        bv[i] = 0;
  178.    while (len-- > 0) {
  179.       c = *image++;
  180.       if (c == '\\')
  181.          c = escape(&image, &len);
  182.       bv[BVectIndx(c)] |= BitInShrt(c);
  183.       }
  184.    return bv;
  185.    }
  186.  
  187. /*
  188.  * cset_init - use bitvector for a cset to write an initialization for
  189.  *    a cset block.
  190.  */
  191. novalue cset_init(f, bv)
  192. FILE *f;
  193. unsigned short *bv;
  194.    {
  195.    int size;
  196.    unsigned short n;
  197.    register int j;
  198.  
  199.    size = 0;
  200.    for (j = 0; j < BVectSize; ++j)
  201.       for (n = bv[j]; n != 0; n >>= 1)
  202.          size += n & 1;
  203.    fprintf(f, "{T_Cset, %d,\n", size);
  204.    fprintf(f, "   cset_display(0x%x", bv[0]);
  205.    for (j = 1; j < BVectSize; ++j)
  206.       fprintf(f, ",0x%x", bv[j]);
  207.    fprintf(f, ")\n    };\n");
  208.    }
  209.  
  210. /*
  211.  * prtstr - print an Icon string literal as a C string literal.
  212.  */
  213. int prt_i_str(f, s, len)
  214. FILE *f;
  215. char *s;
  216. int len;
  217.    {
  218.    int c;
  219.    int n_chars;
  220.  
  221.    n_chars = 0;
  222.    while (len-- > 0) {
  223.       ++n_chars;
  224.       c = *s++;
  225.       if (c == '\\')
  226.          c = escape(&s, &len);
  227.       switch (c) {
  228.          case '\n':
  229.             fprintf(f, "\\n");
  230.             break;
  231.          case '\t':
  232.             fprintf(f, "\\t");
  233.             break;
  234.          case '\v':
  235.             fprintf(f, "\\v");
  236.             break;
  237.          case '\b':
  238.             fprintf(f, "\\b");
  239.             break;
  240.          case '\r':
  241.             fprintf(f, "\\r");
  242.             break;
  243.          case '\f':
  244.             fprintf(f, "\\f");
  245.             break;
  246.          case '\\':
  247.             fprintf(f, "\\\\");
  248.             break;
  249.          case '\"':
  250.             fprintf(f, "\\\"");
  251.             break;
  252.          default:
  253.             if (isprint(c))
  254.                fprintf(f, "%c", c);
  255.             else
  256.                fprintf(f, "\\%03o", (int)c);
  257.          }
  258.       }
  259.    return n_chars;
  260.    }
  261.